﻿using System;
using System.Reflection;
using System.Linq.Expressions;

namespace BluEtch.GotPhone.Helpers
{
    internal sealed class Internal
    {
        /// <summary>
        /// Parses the expression that is passed to GetValue and SetValue to determine the name
        /// of the property that we should access.
        /// Given this expression: () => this.MyProperty
        /// We get the body "this.MyProperty" and pull the member "MyProperty" out of it. Then,
        /// we can use this as the key in the _propertyValues dictionary to retrieve the value.
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="valueSelector"></param>
        /// <returns></returns>
        internal static PropertyInfo GetPropertyInfoFromExpression<TValue>(Expression<Func<TValue>> valueSelector)
        {
            var memberExpression = valueSelector.Body as MemberExpression;
            if (memberExpression == null)
                throw new ArgumentException("Not a valid member expression.", "valueSelector");

            MemberInfo member = ((MemberExpression)valueSelector.Body).Member;
            if (member.MemberType != MemberTypes.Property)
                throw new ArgumentException("Does not describe a property member.", "valueSelector");

            return (PropertyInfo)member;
        }

        internal static bool IsNullable<T>(T obj)
        {
            if (obj == null) return true;
            Type type = typeof(T);
            if (!type.IsValueType) return true; // ref-type
            if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
            return false; // value-type
        }
    }
}
